package com.youlu.campus.admin.card.service;

import com.youlu.campus.admin.card.dto.*;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.card.entity.CardCategory;
import com.youlu.campus.entity.card.entity.CardGoods;
import com.youlu.campus.entity.course.dto.ProductInfo;
import com.youlu.campus.service.course.TxThirdService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author : [dengbo]
 * @className : CardGoodsService
 * @description : [会员卡商品服务]
 * @createTime : [2022/12/17 14:23]
 */
@Service
@Slf4j
public class CardGoodsService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private TxThirdService txThirdService;

    public Page<CardGoods> list(CardGoodsSearchDTO dto) {
        Query query = new Query();
        if (StringUtils.isNotBlank(dto.getGoodsName())) {
            query.addCriteria(Criteria.where("goodsName").is(dto.getGoodsName()));
        }
        if (StringUtils.isNotBlank(dto.getThirdGoodsCode())) {
            query.addCriteria(Criteria.where("thirdGoodsCode").is(dto.getThirdGoodsCode()));
        }
        if (StringUtils.isNotBlank(dto.getFirstCateId())) {
            query.addCriteria(Criteria.where("firstCateId").is(dto.getFirstCateId()));
        }
        if (StringUtils.isNotBlank(dto.getSecondCateId())) {
            query.addCriteria(Criteria.where("secondCateId").is(dto.getSecondCateId()));
        }
        query.addCriteria(Criteria.where("deleted").is(false));
        long count = mongoTemplate.count(query, CardGoods.class);
        query.with(Sort.by(Sort.Order.desc("createdTime")));
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getPageSize());
        List<CardGoods> datas = mongoTemplate.find(query.with(pageRequest), CardGoods.class);
        datas.forEach(item -> {
            Query query1 = new Query();
            query1.addCriteria(Criteria.where("id").in(item.getFirstCateId(), item.getSecondCateId()));
            List<CardCategory> categories = mongoTemplate.find(query1, CardCategory.class);
            Map<String, CardCategory> map = categories.stream().collect(Collectors.toMap(CardCategory::getId, Function.identity(), (o1, o2) -> o2));
            String path = map.get(item.getFirstCateId()).getCateName() + ">" + map.get(item.getSecondCateId()).getCateName();
            item.setPath(path);
        });
        return PageableExecutionUtils.getPage(datas, pageRequest, () -> count);
    }

    public boolean save(CardGoodsSaveDTO dto) {
        Query query = new Query();
        query.addCriteria(Criteria.where("thirdGoodsCode").is(dto.getThirdGoodsCode()));
        query.addCriteria(Criteria.where("deleted").is(false));
        boolean save = StringUtils.isNotBlank(dto.getId());
        if (save) {
            query.addCriteria(Criteria.where("id").ne(dto.getId()));
        }
        CardGoods newGoods = mongoTemplate.findOne(query, CardGoods.class);
        if (newGoods != null) {
            throw new BusinessException("商品编码存在");
        }
        Date date = new Date();
        CardGoods goods;
        if (save) {
            goods = mongoTemplate.findById(dto.getId(), CardGoods.class);
            if (goods == null) {
                throw new BusinessException("商品信息不存在");
            }
        } else {
            goods = new CardGoods();
            goods.setCreatedTime(date);
            goods.setDeleted(false);
        }
        goods.setFirstCateId(dto.getFirstCateId());
        goods.setSecondCateId(dto.getSecondCateId());
        goods.setPrice(dto.getPrice());
        goods.setSalePrice(dto.getSalePrice());
        goods.setOfficialPrice(dto.getOfficialPrice());
        goods.setGoodsName(dto.getGoodsName());
        goods.setGoodsType(dto.getGoodsType());
        goods.setPriority(dto.getPriority());
        goods.setUpdatedTime(date);
        goods.setThirdGoodsCode(dto.getThirdGoodsCode());
        goods.setOnSale(dto.getOnSale());
        goods.setStatus(dto.getStatus());
        if (dto.getMaxQuantity() != null) {
            goods.setMaxQuantity(dto.getMaxQuantity());
        }
        mongoTemplate.save(goods);
        return true;
    }

    /**
     * 删除记录
     *
     * @param saveDTO
     * @return
     */
    public boolean onsale(CardGoodsDeleteDTO saveDTO) {
        CardGoods goods = mongoTemplate.findById(saveDTO.getId(), CardGoods.class);
        if (goods == null) {
            throw new BusinessException("商品信息不存在");
        }
        if (goods.getOnSale()) {
            goods.setOnSale(false);
        } else {
            goods.setOnSale(true);
        }
        mongoTemplate.save(goods);
        return true;
    }

    /**
     * 删除记录
     *
     * @param saveDTO
     * @return
     */
    public boolean delete(CardGoodsDeleteDTO saveDTO) {
        Query query = Query.query(Criteria.where("id").is(saveDTO.getId()));
        Update update = new Update();
        update.set("deleted", true);
        mongoTemplate.updateFirst(query, update, CardGoods.class);
        return true;
    }

    /**
     * 商品价格同步获取
     *
     * @param syncDTO
     * @return
     */
    public ProductInfo syncGoodsPrice(CardGoodsSyncDTO syncDTO) {
        Map<String, Object> result = txThirdService.getGoodsInfo(syncDTO.getGoodsCode());
        ProductInfo info = new ProductInfo();
        info.setName(result.get("name").toString());
        info.setMaxQuantity(Integer.valueOf(String.valueOf(result.get("max_quantity"))));
        BigDecimal decimal = new BigDecimal(String.valueOf(result.get("price"))).multiply(BigDecimal.valueOf(100));
        info.setPrice(decimal.intValue());
        BigDecimal salePrice = decimal.multiply(new BigDecimal("1.1")).setScale(0, RoundingMode.HALF_UP);
        info.setSalePrice(salePrice.intValue());
        Integer officialPrice = new BigDecimal(String.valueOf(result.get("official_price"))).multiply(BigDecimal.valueOf(100)).intValue();
        info.setOfficialPrice(officialPrice);
        info.setStatus(Integer.valueOf(result.get("status").toString()));
        info.setType(Integer.valueOf(String.valueOf(result.get("type"))));
        info.setProductId(syncDTO.getGoodsCode());
        info.setCategoryName(result.get("category_name").toString());
        return info;
    }
}
